package edu.snake.implement.view.controller;

import edu.snake.core.GameEngine;
import edu.snake.core.model.arena.Arena;
import edu.snake.core.service.ViewController;
import edu.snake.core.utils.Listeners;
import edu.snake.implement.model.arena.Direction;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventListener;

import static edu.snake.implement.ConfigConstant.getInstanceThreadPoolService;


public class ViewControllerImpl implements ViewController {

    private final Listeners listeners;
    private final GameEngine gameEngine;

    public ViewControllerImpl(Listeners listeners, GameEngine gameEngine) {
        this.listeners = listeners;
        this.gameEngine = gameEngine;
    }


    @Override
    public void getFromView(String string) {
        Direction direction = Direction.EMPTY;
        if (string.equals("LEFT")) {
            direction = Direction.LEFT;
        } else if (string.equals("RIGHT")) {
            direction = Direction.RIGHT;
        }
        gameEngine.getSnake().setDirection(direction);
    }

    @Override
    public void renderArena(Arena arena) {
        fireActionPerformed(
                new ActionEvent(arena, 0, "render")
        );
    }

    @Override
    public void incrementScore(int score) {
        fireActionPerformed(
                new ActionEvent(score, 0, "incrementScore")
        );
    }

    @Override
    public void startGame() {
        gameEngine.startGame();
    }

    @Override
    public void pauseGame() {
        getInstanceThreadPoolService().pauseThreads();
    }

    @Override
    public void endGameFromViewCommand() {
        gameEngine.stopGame();
    }

    @Override
    public void endGameRender(Arena arena) {
        fireActionPerformed(
                new ActionEvent(arena, 0, "endGame")
        );
    }

    //region Listeners method
    @Override
    public void addActionListener(ActionListener listener) {
        listeners.addActionListener(listener);
    }

    @Override
    public void removeActionListener(ActionListener listener) {
        listeners.removeActionListener(listener);
    }

    @Override
    public ActionListener[] getActionListeners() {
        return listeners.getActionListeners();
    }

    @Override
    public String getActionCommand() {
        return listeners.getActionCommand();
    }

    @Override
    public Object[] getListenerList() {
        return listeners.getListenerList();
    }

    @Override
    public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
        return listeners.getListeners(listenerType);
    }

    //endregion
    protected void fireActionPerformed(ActionEvent e) {
        // Guaranteed to return a non-null array
        Object[] listeners = this.listeners.getListenerList();

        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i] == ActionListener.class) {
                ((ActionListener) listeners[i + 1]).actionPerformed(e);
            }
        }
    }

}
